package org.example.mutithread.future;

import cn.hutool.core.date.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author zhangjg
 * @desc
 * @date 2023/03/30 09:29
 **/
public class CF1 {

    private static final Logger log = LoggerFactory.getLogger(CF1.class);

    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(5);
        long x = DateUtil.current();
        CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> {
            log.info("执行step 1");
            if( x % 2 == 1) {
                throw new RuntimeException("f1 Exception");
            }
            return "step1 result";
        }, executor).exceptionally( e-> {
            log.error("f1 fail {}",e.getMessage());
            return "f1 fail xxx1";
        });

        CompletableFuture<String> cf2 = CompletableFuture.supplyAsync(() -> {
            log.info("执行step 2");
            if( x % 2 == 0) {
                throw new RuntimeException("f2 Exception");
            }
            return "step2 result";
        }).exceptionally( e -> {
            log.error("f2 fail {}",e.getMessage());
            return "f2 fail xxx2";
        });
        cf1.thenCombine(cf2, (result1, result2) -> {
            log.info(result1 + " , " + result2);
            log.info("执行step 3");
            if( x % 2 == 0) {
                throw new RuntimeException("f3 Exception");
            }
            return "step3 result";
        }).exceptionally(e -> {
            log.error("f3 fail {}",e.getMessage());
            return "f3 fail xxx3";
        }).thenAccept(result3 -> {
            log.info("f3 end {}", result3);
            executor.shutdown();
        });
    }

}
